#include <cassert>
#include <cmath>
#include <iostream>
#include <omp.h>

int main() {
    const int N = 1 << 20; // 1M元素
    float *A = new float[N];
    float *B = new float[N];
    float *A_serial = new float[N]; // 用于串行结果对比
    float *B_serial = new float[N]; // 用于串行结果对比

    // 初始化数据
    for (int i = 0; i < N; i++) {
        A[i] = 1.0f;
        A_serial[i] = 1.0f;
    }

    // 串行计算（用于验证正确性）
    for (int i = 1; i < N - 1; i++) {
        B_serial[i] = A_serial[i - 1] + A_serial[i + 1];
    }

#pragma omp for
    for (int i = 1; i < N - 1; i++) {
        B[i] = A[i - 1] + A[i + 1];
    }
#pragma omp for
    for (int i = 1; i < N - 1; i++) {
        A[i] = B[i];
    }

    // 验证结果
    float error_sum = 0;
    for (int i = 1; i < N - 1; i++) {
        error_sum += fabs(A[i] - B_serial[i]); // 对比多线程与串行结果
    }
    assert(error_sum < 1e-6);
    printf("CPU验证通过！结果与串行一致 %.5f\n", error_sum);

    // 多线程计算（迭代100次）
    const int iterations = 100;
    double start_time = omp_get_wtime();
    for (int iter = 0; iter < iterations; iter++) {
#pragma omp parallel
        {
#pragma omp for
            for (int i = 1; i < N - 1; i++) {
                B[i] = A[i - 1] + A[i + 1];
            }
#pragma omp for
            for (int i = 1; i < N - 1; i++) {
                A[i] = B[i];
            }
        }
    }
    double cpu_time_ms = (omp_get_wtime() - start_time) * 1000;

    printf("CPU平均耗时: %.3f ms\n", cpu_time_ms / iterations);

    delete[] A;
    delete[] B;
    delete[] A_serial;
    return 0;
}
